package br.unifor.sd.bolsa.cliente.impl;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import br.unifor.sd.bolsa.interfaces.ClienteInterface;
import br.unifor.sd.bolsa.interfaces.ListListener;
import br.unifor.sd.bolsa.util.Acao;
import br.unifor.sd.bolsa.util.Dialeto;

/**
 *
 * @author andrea
 */
public class ClienteImplUDP implements ClienteInterface {

	private DatagramSocket socket;
	private DatagramPacket pacote;
    private InetAddress address;
	private Integer porta;
    private String dono;
    private Boolean ligado;

    /**
     * Implementação de listener para notificar tela ao chegar uma nova mensagem.
     */
    private List<ListListener> listeners;

    public ClienteImplUDP() {
        ligado = Boolean.TRUE;
        listeners = new ArrayList<ListListener>();
    }

    public void conectar(String ip, Integer porta) throws Exception {
        this.socket = new DatagramSocket();
        this.address = InetAddress.getByName(ip);
        this.porta = porta;
    }

    public void encerrarConexao() throws Exception {
        socket.close();
        ligado = Boolean.FALSE;
    }

    public void escutar() {
        try {
        	byte [] bytes = new  byte[1024];
        	DatagramPacket pacote = new DatagramPacket(bytes, bytes.length);
        	while(ligado)
        	{
        		socket.receive(pacote);
        		String conteudo = new String(pacote.getData(), 0, pacote.getLength());
        		message(Dialeto.listaStringToList(conteudo));
        		pacote.setLength(bytes.length);
        	}
        } catch (IOException ex) {
            Logger.getLogger(ClienteImplUDP.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void addListener(ListListener listener) {
        listeners.add(listener);
    }

    public void message(List <Acao> lista) {
        for (int i = 0; i < listeners.size(); i++) {
            listeners.get(i).onMessage(lista);
        }
    }

    public void iniciar() throws IOException {
		byte[] dados = "iniciar ".getBytes();
		enviar(dados);
    }

    public void comprarAcao(Integer acaoId) throws IOException{
        byte[] dados = Dialeto.comprarToString(acaoId, this.dono).getBytes();
        enviar(dados);
    }

    public void comprarAcaoValor(Integer acaoId,Double valor) throws IOException{
        byte[] dados = Dialeto.comprarComValorToString(acaoId, this.dono, valor).getBytes();
        enviar(dados);
    }

    public void venderAcao(Integer acaoId) throws IOException {
        byte[] dados = Dialeto.venderToString(acaoId, this.dono).getBytes();
        enviar(dados);
    }
    
    private void enviar(byte[] dados) throws IOException {
		pacote = new DatagramPacket(dados, dados.length, this.address, this.porta);
		socket.send(pacote);	
    }

    /**
     * @return the dono
     */
    public String getDono() {
        return dono;
    }

    /**
     * @param dono the dono to set
     */
    public void setDono(String dono) {
        this.dono = dono;
    }
}
